open Ast
open Tokens
open Subs
open OpBloc
open OpGraph
open Utils
open ToBePrinted

let update b =
  b.bools<-[];
  b.rego<-[];
  for i=0 to (b.nbElem-1) do
    if b.noeuds.(i)=FALSE || b.noeuds.(i)=TRUE then
      b.bools<-(i::b.bools);
    if b.noeuds.(i)=REGOUT then begin
      b.rego<-i::b.rego
    end
  done;;



let _ =
  let lexbuf = Lexing.from_channel stdin in
  let ast = List.hd (simplify (Grammar.program cacheHandler lexbuf)) in
  readProgram ast;
  let main = Hashtbl.find func "main" in
  update main;
  optimize main;
  update main;
  let (correspondance,lim) = tri_top main in 
  let id = ref (-1) in
  let couples = Array.map (function x -> incr id;(x,!id)) correspondance in
  let toPrint = revert main (correspondance,lim) in
  let f x y = (compare (fst x) (fst y)) in
  Array.sort f couples;
  print_int (lim+1);print_newline();
  for noeud=0 to lim do
    let realId =snd (couples.(noeud)) in
    let args = ref toPrint.ladj.(realId) in

    if toPrint.noeuds.(realId)==REGOUT then
      args:=(!args)@[(toPrint.link.(realId))];


    afficheType toPrint.noeuds.(realId);print_string " ";print_int (List.length (!args));print_string " ";
    List.iter (function x -> print_int (correspondance.(x) );print_string " ") (!args); 
    if (Hashtbl.mem toBePrinted (toPrint.names.(realId))) then 
      print_string ("T "^toPrint.names.(realId))
    else 
      print_string "N";
  print_newline();
  done;
  print_int (Hashtbl.length addrToPrintRam);print_newline();
  Hashtbl.iter (fun x-> fun y -> print_int x;print_newline()) addrToPrintRam;
  print_int (Hashtbl.length addrToPrintRom);print_newline();
  Hashtbl.iter (fun x-> fun y -> print_int x;print_newline()) addrToPrintRom;;
